package reversi.servidor;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.sql.Connection;
import java.util.ArrayList;

import org.w3c.dom.Document;

import reversi.xml.XmlParser;
import reversi.db.MenejadorDb;

//public class HiloDeCliente implements Runnable, ListDataListener  {
public class HiloDeCliente extends Thread implements Runnable {
	/** Socket al que esta conectado el cliente */
	private Socket socket;

	/** Para lectura de datos en el socket */
	private DataInputStream dataInput;

	/** Para escritura de datos en el socket */
	private DataOutputStream dataOutput;
	
	//Para relacionar a cada usuario con un socket
	private String usuario;
	
	XmlParser xml = new XmlParser();
	
	private ArrayList<String> datos = new ArrayList<String>(10) ;
	
	Connection conPostgres=null;
	
	MenejadorDb Db = new MenejadorDb();

	/**
	 * Crea una instancia de esta clase y se suscribe a cambios en la charla.
	 * 
	 * @param charla
	 *            La lista de textos que componen la charla del chat
	 * @param socket
	 *            Socket con el cliente.
	 */
	public HiloDeCliente(Socket socket, Connection conPostgres) {
		this.socket = socket;
		this.conPostgres=conPostgres;
		this.usuario="";
		try {
			/*
			 * Inicializamos el dataInput para recibir los mensajes desde cada
			 * cliente conectado a un Socket
			 */
			dataInput = new DataInputStream(socket.getInputStream());
			/*
			 * Inicializamos el dataOutput con cada Socket 
			 */
			dataOutput = new DataOutputStream(socket.getOutputStream());

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// metodo para poner el boolean a false.
	   @SuppressWarnings("deprecation")
	public void detenerHilo()
	   {
	      this.stop();
	   }
	/**
	 * Atiende el socket. Todo lo que llega lo mete en la charla.
	 */
	public void run() {
		try {
			while (true) {
				/*
				 * El thread se bloquea esperando a leer un String de cada
				 * socket conectado
				 */
				String texto = dataInput.readUTF();
				//System.out.println(texto);
				//Lo que recibimos a traves del socket lo pasamos a xml
				Document textoXml = xml.string2DOM(texto);
				
				String respuesta="";
				
				
				//guarda los datos extraidos del xml, datos[0] la operacio, datos[1] el usuario
				//datos[2] la contraseña
				datos=xml.getDatos(textoXml);
				
				if(datos.get(0).equalsIgnoreCase("registrarse")){
					//Controla si ya exite un usuario con ese nombre
					if(!Db.existeDb(conPostgres, datos.get(1))){
						//Se debe enviar un mensaje que diga: has sido agregado, y quedar conectado
						//Inserta al usuario en la DB
						Db.InsertDb(conPostgres, datos.get(1), datos.get(2));
						//Almanacena el nombre del usuario
						this.usuario=datos.get(1);
						//Genera la respuesta para el cliente
						//respuesta= xml.crearXml("respuesta", "registrado");
						System.out.println(datos.get(1)+" se ha registrado y e iniciado sesion");
						respuesta= xml.crearXml("registrarse", "si");
						dataOutput.writeUTF(respuesta);
					}else{
						respuesta= xml.crearXml("registrarse", "no");
						dataOutput.writeUTF(respuesta);
						System.out.println(datos.get(1)+" ya existe un usuario con ese nombre");
					}
				}else if(datos.get(0).equalsIgnoreCase("conectarse")){	
					//Autentificacion de usuario
					if(Db.existeDb(conPostgres, datos.get(1), datos.get(2))){
						//Actualiza el estado de conectado del usuario
						Db.updateConectadoDb(conPostgres, datos.get(1));
						//Almanacena el nombre del usuario
						this.usuario=datos.get(1);
						//Genera la respuesta para el cliente
						System.out.println(datos.get(1)+" ha iniciado sesion");
						respuesta= xml.crearXml("conectarse", "si");
						dataOutput.writeUTF(respuesta);
					}else{
						respuesta= xml.crearXml("conectarse", "no");
						dataOutput.writeUTF(respuesta);
						System.out.println(datos.get(1)+" nombre de usuario y contraseña no coinciden");
					}
				}else if(datos.get(0).equalsIgnoreCase("actualizar")){
					//System.out.println("actualizar");
					//respuesta = Db.SelectDb(conPostgres);
					respuesta= xml.crearXml("actualizar", Db.SelectDb(conPostgres));
					dataOutput.writeUTF(respuesta);
					//System.out.println(respuesta);
				//si se desea empezar una partida	
				}else if(datos.get(0).equalsIgnoreCase("empezar")){
					
					for (int i = 0; i < ServidorReversi.clientes.size() ; i ++)
	        		{
	        			HiloDeCliente t = (HiloDeCliente)ServidorReversi.clientes.get(i);
	        			//busca si uno de los hilos del servidor es del usuario con el cual 
	        			//se desea jugar
	        			if (t.usuario.equals(datos.get(1)))
	        			{
	        				respuesta= xml.crearXml("empezar",this.usuario,datos.get(2),datos.get(3));
	        				t.dataOutput.writeUTF(respuesta);
	        				break;
	        			}
	        		}
				
				}else if(datos.get(0).equalsIgnoreCase("jugada")){
					for (int i = 0; i < ServidorReversi.clientes.size() ; i ++)
	        		{
	        			HiloDeCliente t = (HiloDeCliente)ServidorReversi.clientes.get(i);
	        			//busca si uno de los hilos del servidor es del usuario con el cual 
	        			//se desea jugar
	        			if (t.usuario.equals(datos.get(1)))
	        			{
	        				respuesta= xml.crearXml("jugada",datos.get(2),datos.get(3));
	        				t.dataOutput.writeUTF(respuesta);
	        				break;
	        			}
	        		}
				}else if(datos.get(0).equalsIgnoreCase("terminar")){
					for (int i = 0; i < ServidorReversi.clientes.size() ; i ++)
	        		{
	        			HiloDeCliente t = (HiloDeCliente)ServidorReversi.clientes.get(i);
	        			//busca si uno de los hilos del servidor es del usuario con el cual 
	        			//se desea jugar
	        			if (t.usuario.equals(datos.get(1)))
	        			{
	        				respuesta= xml.crearXml("terminar",this.usuario,datos.get(2));
	        				t.dataOutput.writeUTF(respuesta);
	        				
	        				
	        				break;
	        			}
	        		}
				}else if(datos.get(0).equalsIgnoreCase("desconectarse")){
					respuesta= xml.crearXml("desconectarse", datos.get(1));
					//Actualiza el estado de conectado del usuario
					Db.updateDesconectadoDb(conPostgres, datos.get(1));
					dataOutput.writeUTF(respuesta);
					//Quita el hilo del usuario de la lista de hilos
					ServidorReversi.clientes.remove(this);
					socket.close();
					System.out.println(datos.get(1)+" ha cerrado sesion");
					detenerHilo();
				}else if(datos.get(0).equalsIgnoreCase("ocupado")){
					Db.updateOcupadoDb(conPostgres, datos.get(1), datos.get(2));
					System.out.println(datos.get(1)+" "+datos.get(2)+" esta ocupado");
				}else if(datos.get(0).equalsIgnoreCase("borrar")){
					Db.deleteDb(conPostgres, datos.get(1));
					System.out.println(datos.get(1)+" ha borrado su cuenta");
					respuesta= xml.crearXml("borrar", datos.get(1));
					dataOutput.writeUTF(respuesta);
					//Quita el hilo del usuario de la lista de hilos
					ServidorReversi.clientes.remove(this);
					socket.close();
					detenerHilo();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public boolean equals(HiloDeCliente c)
	{
		return (c.usuario.equals(this.usuario));
	}
}
